<template>
  <a-form-model
    class="article-input"
    ref="form"
    :model="model"
    :rules="rules"
    :label-col="FORM_LAYOUT.labelCol"
    :wrapper-col="FORM_LAYOUT.wrapperCol">
    <a-row class="form-row" :gutter="16">
      <a-col :lg="18">
        <a-card title="文章信息" :bordered="false">
          <a-form-model-item
            label="标题"
            :labelCol="FULL_FORM_LAYOUT.labelCol"
            :wrapperCol="FULL_FORM_LAYOUT.wrapperCol"
            prop="title">
            <a-input v-model="model.title" />
          </a-form-model-item>
          <a-form-model-item
            label="副标题"
            :labelCol="FULL_FORM_LAYOUT.labelCol"
            :wrapperCol="FULL_FORM_LAYOUT.wrapperCol"
            prop="subtitle">
            <a-input v-model="model.subtitle" />
          </a-form-model-item>
          <a-form-model-item
            label="内容"
            :labelCol="FULL_FORM_LAYOUT.labelCol"
            :wrapperCol="FULL_FORM_LAYOUT.wrapperCol"
            prop="content">
            <div id="content"></div>
          </a-form-model-item>
          <div class="input-btn-group">
            <e-btn-save permissions="cms:article:save" :loading="saveLoading" :click-callback="save" />

            <a-button
              v-if="$permissions('cms:article:save')"
              type="primary"
              icon="save"
              :loading="btnLoading"
              @click="save(release)">
              保存并发布
            </a-button>
            <a-button
              v-if="$permissions('cms:article:save')"
              type="primary"
              icon="plus"
              :loading="btnLoading"
              @click="save(create)">
              保存并新增
            </a-button>
          </div>
        </a-card>
      </a-col>
      <a-col :lg="6">
        <a-card
          style="width:100%"
          :tab-list="cardTab"
          :active-tab-key="cardTabKey"
          @tabChange="key => onTabChange(key)"
        >
          <div v-if="cardTabKey === 'base'">
            <a-form-model-item label="状态" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <e-dict-tag type="cmsArticleStatus" :code="model.status" />
            </a-form-model-item>
            <a-form-model-item label="栏目" prop="columnId" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <cascader :options="columnTree" placeholder="请选择栏目" :show-search="{ columnFilter }" v-model="columnId" @change="setColumn" />
            </a-form-model-item>
            <a-form-model-item label="封面" prop="cover" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <div class="ant-upload-preview" @click="changeCover">
                <div class="mask">
                  <a-icon type="plus" />
                </div>
                <img
                  v-if="model.cover && model.cover.url && model.cover.url !== ''"
                  :src="VUE_APP_API_BASE_URL + model.cover.url" />
                <a-avatar shape="square" v-else :size="160" icon="file-image" />
              </div>
            </a-form-model-item>
            <a-form-model-item label="发布方式" prop="releaseType" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }" v-show="false">
              <e-dict-radio type="cmsArticleReleaseType" v-model="model.releaseType" />
            </a-form-model-item>
            <a-form-model-item
              label="上线时间"
              :label-col="{ span: 6 }"
              :wrapper-col="{ span: 16 }"
              v-if="model.releaseType === '2'">
              <a-date-picker
                v-model="startValue"
                :disabled-date="disabledStartDate"
                show-time
                format="YYYY-MM-DD HH:mm:ss"
                @openChange="handleStartOpenChange"
              />
            </a-form-model-item>
            <a-form-model-item
              label="下线时间"
              :label-col="{ span: 6 }"
              :wrapper-col="{ span: 16 }"
              v-if="model.releaseType === '2'">
              <a-date-picker
                v-model="endValue"
                :disabled-date="disabledEndDate"
                show-time
                format="YYYY-MM-DD HH:mm:ss"
                :open="endOpen"
                @openChange="handleEndOpenChange"
              />
            </a-form-model-item>
            <a-form-model-item label="作者" prop="author" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <a-input v-model="model.author" />
            </a-form-model-item>
            <a-form-model-item label="摘要" prop="excerpt" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <a-textarea v-model="model.excerpt" style="height: 80px"/>
            </a-form-model-item>
            <a-form-model-item prop="tags" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <span slot="label">
                标签
                <a-tooltip title="支持多个，输入后按回车键输入下一个标签">
                  <a-icon type="question-circle-o" />
                </a-tooltip>
              </span>

              <a-select mode="tags" v-model="tagArray"/>
            </a-form-model-item>
            <a-form-model-item label="信息来源" prop="source" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <a-input v-model="model.source" />
            </a-form-model-item>
            <a-form-model-item prop="url" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <span slot="label">
                访问地址
                <a-tooltip title="填写此项时点击文章链接将打开填写的访问地址">
                  <a-icon type="question-circle-o" />
                </a-tooltip>
              </span>
              <a-input v-model="model.url" />
            </a-form-model-item>
          </div>
          <div v-else-if="cardTabKey === 'seo'">
            <a-form-model-item label="关键字" prop="keyword" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <a-textarea v-model="model.keyword" />
            </a-form-model-item>
            <a-form-model-item label="描述" prop="description" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
              <a-textarea v-model="model.description" />
            </a-form-model-item>
          </div>
        </a-card>
      </a-col>
    </a-row>

    <cover-modal ref="modal" @ok="setCover" :img="model.cover && model.cover.url && model.cover.url !== '' ? (VUE_APP_API_BASE_URL + model.cover.url) : null"/>
    <cms-chose-site @change="changeSite" />

    <a-modal
      title="上传资源"
      :visible="uploadModalVisible"
    >
      <a-alert :message="updateMessage" type="info" show-icon />
      <br/>

      <a-upload
        name="file"
        :accept="accept"
        :multiple="true"
        :action="`${VUE_APP_API_BASE_URL}/auth/file/upload`"
        :headers="headers"
        :file-list="files"
        :before-upload="beforeUpload"
        :remove="handleRemove"
        @change="handleChange"
        @cancel="() => {this.uploadModalVisible = false}"
      >
        <a-button>
          <a-icon type="upload"/>
          选择文件
        </a-button>
      </a-upload>

      <template slot="footer">
        <a-button @click="() => {this.uploadModalVisible = false}">
          关闭
        </a-button>
      </template>
    </a-modal>

    <a-modal
      title="资源库"
      :width="1048"
      :visible="mediaModalVisible"
      @cancel="() => {this.mediaModalVisible = false}"
    >
      <div class="media-query">
        <a-radio-group v-model="mediaType" @change="changeMediaType">
          <a-radio-button v-for="item in mediaTypeArray" :key="item.value" :value="item.value">
            {{ item.label }}
          </a-radio-button>
        </a-radio-group>

        <a-input-search placeholder="请输入关键字查询" style="width: 260px;margin-left: 10px"/>
      </div>
      <div class="media-data">
        <div class="media-items">
          <div @click="onMediaItemClick(item)" @dblclick="onMediaItemDblclick(item)" :class="getMediaItemClass(item)" v-for="item in mediaData" :key="item.id">
            <div class="media-item-body">
              <div class="media-item-preview">
                <template v-if="item.type === 'image'">
                  <img :src="VUE_APP_API_BASE_URL + item.filePath">
                </template>
                <template v-if="item.type === 'video'">
                  <a-icon type="video-camera" />
                </template>
                <template v-if="item.type === 'audio'">
                  <a-icon type="audio" />
                </template>
                <template v-if="item.type === 'doc'">
                  <a-icon v-if="item.name.indexOf('.md') > -1" type="file-markdown" />
                  <a-icon v-else-if="item.name.indexOf('.pdf') > -1" type="file-pdf" />
                  <a-icon v-else-if="item.name.indexOf('.ppt') > -1 || item.name.indexOf('.pptx') > -1" type="file-ppt" />
                  <a-icon v-else-if="item.name.indexOf('.txt') > -1" type="file-text" />
                  <a-icon v-else-if="item.name.indexOf('.doc') > -1 || item.name.indexOf('.docx') > -1" type="file-word" />
                  <a-icon v-else-if="item.name.indexOf('.xls') > -1 || item.name.indexOf('.xlsx') > -1" type="file-excel" />
                  <a-icon v-else type="file-unknown" />
                </template>
                <template v-if="item.type === 'other'">
                  <a-icon type="file" />
                </template>
              </div>

              <a-tooltip :title="item.name">
                <span class="media-item-name e-ell">{{ item.name }}</span>
              </a-tooltip>
            </div>
          </div>
        </div>

        <a-pagination
          style="float: right"
          size="small"
          v-model="mediaPage.current"
          :total="mediaPage.total"
          :page-size.sync="mediaPage.pageSize"
          :show-total="(total, range) => `第 ${range[0]}-${range[1]} 条/总共 ${total} 条`"
          show-size-changer
          @change="loadMedia"
          @showSizeChange="loadMedia"/>
      </div>

      <template slot="footer">
        <a-alert
          message="双击文件可快速插入"
          type="info"
          class="insert-alert"
          show-icon
          banner/>
        <a-button @click="() => {this.mediaModalVisible = false}">
          关闭
        </a-button>
        <a-button type="primary" @click="insertChoseMediaToHTML">
          插入
        </a-button>
      </template>
    </a-modal>
  </a-form-model>

</template>

<script>
import { Cascader, Pagination as APagination } from 'ant-design-vue'
import { FULL_FORM_LAYOUT, FORM_LAYOUT } from '@/utils/const/form'
import { add, get, release, save } from '@/api/cms/article'
import { save as saveMedia, select as selectMedia } from '@/api/cms/media'
import { saveSuccessTip } from '@/utils/tips'
import { convertTree, findPathById, getSysDictArrayByDictType, isNotBlank } from '@/utils/util'
import EBtnSave from '@/components/Easy/general/BtnSave'
import { DATE_PATTERN } from '@/utils/const/datePattern'
import EDatePicker from '@/components/Easy/data-entry/DatePicker'
import CoverModal from '@/views/cms/article/CoverModal'
import { selectColumnsByUserId } from '@/api/cms/column/user'
import CmsChoseSite from '@/views/cms/ChoseSite'
import WangEditor from 'wangeditor'
import moment from 'moment'
import storage from 'store'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import EDictTag from '@/components/Easy/data-display/DictTag'
import { CMS_ARTICLE_CONST } from '@/utils/const/cms/CmsArticleConst'
import EDictRadio from '@/components/Easy/data-entry/DictRadio'

export default {
  name: 'CmsArticleInput',
  components: {
    EDictRadio,
    EDictTag,
    CmsChoseSite,
    Cascader,
    CoverModal,
    EBtnSave,
    EDatePicker,
    WangEditor,
    APagination
  },
  data () {
    return {
      VUE_APP_API_BASE_URL: process.env.VUE_APP_API_BASE_URL,

      id: this.$route.query.id,

      cardTab: [
        {
          key: 'base',
          tab: '基本信息'
        },
        {
          key: 'seo',
          tab: 'SEO'
        }
      ],
      cardTabKey: 'base',

      FULL_FORM_LAYOUT: FULL_FORM_LAYOUT,
      FORM_LAYOUT: FORM_LAYOUT,
      DATE_PATTERN: DATE_PATTERN,

      // 资源库
      mediaModalVisible: false,
      mediaType: 'all',
      mediaTypeArray: [{ label: '全部', value: 'all' }],
      mediaData: [],
      mediaPage: { total: 0, current: 1, pageSize: 10 },
      choseMedia: [],
      // 表单
      btnLoading: false,
      uploadModalVisible: false,
      accept: '',
      updateMessage: '',
      insertType: null,
      headers: {
        'Access-Token': storage.get(ACCESS_TOKEN)
      },
      maxFileSize: 512,
      files: [],

      editor: null,
      saveLoading: false,
      model: {
        cover: {}
      },
      tagArray: [],
      startValue: null,
      endValue: null,
      endOpen: false,
      // 栏目数据
      column: [],
      columnTree: [],
      columnId: [],
      rules: {
        title: [
          { required: true, message: '请输入标题', trigger: 'blur' },
          { max: 64, message: '标题不能超过64个字符', trigger: 'blur' }
        ],
        subtitle: [
          { max: 128, message: '副标题不能超过128个字符', trigger: 'blur' }
        ],
        columnId: [
          { required: true, message: '请选择栏目', trigger: 'change' }
        ],
        excerpt: [
          { max: 256, message: '摘要不能超过256个字符', trigger: 'blur' }
        ],
        content: [
          { max: 10000, message: '内容不能超过10000个字符', trigger: 'blur' }
        ],
        keyword: [
          { max: 32, message: '关键字不能超过32个字符', trigger: 'blur' }
        ],
        description: [
          { max: 256, message: '描述不能超过256个字符', trigger: 'blur' }
        ],
        source: [
          { max: 32, message: '信息来源不能超过32个字符', trigger: 'blur' }
        ],
        author: [
          { max: 8, message: '作者不能超过8个字符', trigger: 'blur' }
        ],
        url: [
          { max: 256, message: '访问地址不能超过256个字符', trigger: 'blur' }
        ]
      }
    }
  },
  mounted () {
    this.initPage()

    // 媒体字典
    const dicts = getSysDictArrayByDictType('cmsMediaType')
    dicts.map(item => {
      this.mediaTypeArray.push({
        value: item.code,
        label: item.name
      })
    })
  },
  watch: {
    startValue (val) {
      this.model.releaseDate = val.format('YYYY-MM-DD HH:mm:ss')
    },
    endValue (val) {
      this.model.offlineDate = val.format('YYYY-MM-DD HH:mm:ss')
    }
  },
  methods: {
    initPage () {
      this.initEditor()
      if (isNotBlank(this.id)) {
        this.edit(this.id)
      } else {
        this.create()
      }
    },
    /**
     * 初始化编辑器
     */
    initEditor () {
      const menuMediaImageKey = 'mediaImage'
      const menuMediaVideoKey = 'mediaVideo'
      const menuMediaFileKey = 'mediaFile'
      const menuMediaKey = 'media'

      const { BtnMenu } = WangEditor
      const vm = this
      class mediaImageMenu extends BtnMenu {
        constructor (editor) {
          // data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
          const $elem = WangEditor.$(`<div class="w-e-menu" data-title="图片"><i class="w-e-icon-image"></i></div>`)
          super($elem, editor)
        }
        // 菜单点击事件
        clickHandler () {
          vm.uploadModalVisible = true
          vm.insertType = 'image'
          vm.accept = 'image/*'
          vm.updateMessage = '支持上传图片文件'
        }
        tryChangeActive () {}
      }
      class mediaVideoMenu extends BtnMenu {
        constructor (editor) {
          // data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
          const $elem = WangEditor.$(`<div class="w-e-menu" data-title="视频"><i class="w-e-icon-play"></i></div>`)
          super($elem, editor)
        }
        // 菜单点击事件
        clickHandler () {
          vm.uploadModalVisible = true
          vm.insertType = 'video'
          vm.accept = 'video/*'
          vm.updateMessage = '支持上传视频文件'
        }
        tryChangeActive () {}
      }
      class mediaFileMenu extends BtnMenu {
        constructor (editor) {
          // data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
          const $elem = WangEditor.$(`<div class="w-e-menu" data-title="附件"><i aria-label="图标: paper-clip" class="anticon anticon-paper-clip"><svg viewBox="64 64 896 896" data-icon="paper-clip" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0 0 12.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 0 0 174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"></path></svg></i></div>`)
          super($elem, editor)
        }
        // 菜单点击事件
        clickHandler () {
          vm.uploadModalVisible = true
          vm.insertType = 'file'
          vm.accept = '.doc,.docx,.xlsx,.xls,.ppt,.pptx,.pdf,.txt,.zip,.7z,.rar'
          vm.updateMessage = '支持上传.doc,.docx,.xlsx,.xls,.ppt,.pptx,.pdf,.txt,.zip,.7z,.rar文件'
        }
        tryChangeActive () {}
      }
      class mediaMenu extends BtnMenu {
        constructor (editor) {
          // data-title属性表示当鼠标悬停在该按钮上时提示该按钮的功能简述
          const $elem = WangEditor.$(`<div class="w-e-menu" data-title="资源库"><i aria-label="图标: folder" class="anticon anticon-folder"><svg viewBox="64 64 896 896" data-icon="folder" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M880 298.4H521L403.7 186.2a8.15 8.15 0 0 0-5.5-2.2H144c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V330.4c0-17.7-14.3-32-32-32zM840 768H184V256h188.5l119.6 114.4H840V768z"></path></svg></i></div>`)
          super($elem, editor)
        }
        // 菜单点击事件
        clickHandler () {
          vm.mediaModalVisible = true
          vm.loadMedia()
        }
        tryChangeActive () {}
      }
      const editor = new WangEditor('#content')
      editor.config.menus = [
        'head',
        'bold',
        'fontSize',
        'fontName',
        'italic',
        'underline',
        'strikeThrough',
        'indent',
        'lineHeight',
        'foreColor',
        'backColor',
        'link',
        'list',
        'todo',
        'justify',
        'quote',
        'emoticon',
        'table',
        'splitLine',
        'undo',
        'redo'
      ]

      editor.config.zIndex = 1
      // 配置 onchange 回调函数，将数据同步到 vue 中
      editor.config.onchange = (newHtml) => {
        this.model.content = newHtml
      }
      editor.menus.extend(menuMediaImageKey, mediaImageMenu)
      editor.menus.extend(menuMediaVideoKey, mediaVideoMenu)
      editor.menus.extend(menuMediaFileKey, mediaFileMenu)
      editor.menus.extend(menuMediaKey, mediaMenu)

      editor.config.menus = editor.config.menus.concat(menuMediaImageKey)
      editor.config.menus = editor.config.menus.concat(menuMediaVideoKey)
      editor.config.menus = editor.config.menus.concat(menuMediaFileKey)
      editor.config.menus = editor.config.menus.concat(menuMediaKey)

      // 创建编辑器
      editor.create()
      this.editor = editor
    },
    /**
     * 加载栏目数据
     */
    loadColumns () {
      selectColumnsByUserId().then(({ data }) => {
        this.column = data
        this.convertCascaderData()
      })
    },
    /**
     * 将栏目数据转为级联选择所需的数据格式
     */
    convertCascaderData () {
      function convert (tempColumnTree) {
        const node = []
        for (let i = 0; i < tempColumnTree.length; i += 1) {
          if (tempColumnTree[i].children && tempColumnTree[i].children.length) {
            node.push({
              value: tempColumnTree[i].id,
              label: tempColumnTree[i].name,
              children: convert(tempColumnTree[i].children)
            })
          } else {
            node.push({
              value: tempColumnTree[i].id,
              label: tempColumnTree[i].name
            })
          }
        }
        return node
      }

      this.columnTree = convert(convertTree(this.column, '0'))
      this.getColumn()
    },
    /**
     * 获取栏目每一级的id
     */
    getColumn () {
      if (this.model.columnId == null || this.model.columnId === '') {
        this.columnId = []
      } else {
        this.columnId = findPathById(this.columnTree, this.model.columnId, [], 'value')
      }
    },
    /**
     * 设置栏目
     *
     * @param value {array} 选中的值 ['1', '1-1', '1-1-1']
     */
    setColumn (value) {
      if (value.length) {
        this.model.columnId = value[value.length - 1]
      } else {
        this.model.columnId = null
      }
    },
    columnFilter (inputValue, path) {
      return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1)
    },
    /**
     * 更改站点
     */
    changeSite () {
      this.initPage()
    },
    /**
     * 修改封面
     */
    changeCover () {
      let scale = null
      if (this.model.columnId) {
        for (let i = 0; i < this.column.length; i++) {
          if (this.column[i].id === this.model.columnId) {
            const { coverProportionWidth, coverProportionHeight } = this.column[i]
            if (coverProportionWidth && coverProportionHeight) {
              scale = coverProportionWidth / coverProportionHeight
            }
          }
        }
      }
      this.$refs.modal.edit(scale)
    },
    /**
     * 设置封面
     *
     * @param data {object} 上传文件返回数据
     */
    setCover (data) {
      this.model.cover = Object.assign(data)
    },
    onTabChange (key) {
      this.cardTabKey = key
    },
    edit (id) {
      get(id).then((res) => {
        this.model = res.data
        if (this.model.content) {
          this.editor.txt.html(this.model.content)
        }
        if (this.model.releaseDate) {
          this.startValue = moment(this.model.releaseDate)
        }
        if (this.model.offlineDate) {
          this.endValue = moment(this.model.offlineDate)
        }
        if (this.model.tags) {
          this.tagArray = this.model.tags.split(',')
        } else {
          this.tagArray = []
        }

        this.loadColumns()
      })
    },
    create () {
      add(this.$route.query.columnId).then((res) => {
        this.model = res.data
        if (this.model.tags) {
          this.tagArray = this.model.tags.split(',')
        } else {
          this.tagArray = []
        }
        // 清空编辑器内容
        this.editor.txt.html('')
        this.loadColumns()
      })
    },
    save (callback) {
      this.$refs.form.validate(valid => {
        if (valid) {
          this.saveLoading = true
          this.model.tags = this.tagArray.join(',')
          save(this.model).then((res) => {
            this.saveLoading = false
            saveSuccessTip()
            this.model = res.data

            if (callback) {
              callback(res.data)
            }
          }).catch(({ response }) => {
            this.saveLoading = false
          })
        }
      })
    },
    /**
     * 发布
     *
     * @param id {string} id
     */
    release ({ id }) {
      release(id).then(res => {
        this.model.status = CMS_ARTICLE_CONST.PUBLISHED
        this.$message.success(`发布成功`)
      })
    },

    // start: 发布时间 & 下线时间
    disabledStartDate (startValue) {
      const endValue = this.endValue
      if (!startValue || !endValue) {
        return false
      }
      return startValue.valueOf() > endValue.valueOf()
    },
    disabledEndDate (endValue) {
      const startValue = this.startValue
      if (!endValue || !startValue) {
        return false
      }
      return startValue.valueOf() >= endValue.valueOf()
    },
    handleStartOpenChange (open) {
      if (!open) {
        this.endOpen = true
      }
    },
    handleEndOpenChange (open) {
      this.endOpen = open
    },
    // end: 发布时间 & 下线时间
    /**
     * 上传资源库时取消上传
     *
     * @param file
     */
    handleRemove (file) {
      const index = this.files.indexOf(file)
      const newFileList = this.files.slice()
      newFileList.splice(index, 1)
      this.files = newFileList
    },
    /**
     * 上传资源库之前
     *
     * @param file
     * @return {boolean}
     */
    beforeUpload (file) {
      if (file.size / 1024 / 1024 > this.maxFileSize) {
        this.$message.error(`文件大小超出限制，不能超过${this.maxFileSize}MB`)
        return false
      }
      return true
    },
    handleChange (info) {
      if (info.file.status) {
        if (info.file.status === 'done') {
          this.saveMedia(info.file.response.data)
        } else if (info.file.status === 'error') {
          this.$message.error(`${info.file.name || ''} 上传失败`)
        }
        this.files = info.fileList.filter(item => item.status !== 'done')
      }
    },
    /**
     * 保存上传的文件到资源库
     *
     * @param name {string} 显示名称
     * @param path {string} 路径
     */
    saveMedia ({ name, path }) {
      saveMedia({ file: { displayName: name, path } }).then(res => {
        this.$message.success(`${res.data.name} 上传成功`)
        this.insertHTML(res.data)
        this.uploadModalVisible = false
      })
    },
    insertHTML (media) {
      const url = this.VUE_APP_API_BASE_URL + (media.file ? media.file.url : media.filePath)
      if (media.type === 'image') {
        this.editor.cmd.do('insertHTML', `<img class="cms-media cms-media-image" alt="${media.name}" src="${url}"/>`)
      } else if (media.type === 'video') {
        this.editor.cmd.do('insertHTML', `<video class="cms-media cms-media-video" controls src="${url}">${media.name}</video>`)
      } else {
        this.editor.cmd.do('insertHTML', `<a class="cms-media cms-media-file" target="_blank" href="${url}">${media.name}</a>`)
      }
    },
    /**
     * 切换资源类型时加载数据
     */
    changeMediaType () {
      this.loadMedia()
    },
    loadMedia () {
      selectMedia({
        type: this.mediaType === 'all' ? '' : this.mediaType,
        ...this.mediaPage
      }).then(res => {
        this.choseMedia = []
        this.mediaData = res.data.data
        this.mediaPage = {
          current: res.data.current,
          pageSize: res.data.pageSize,
          total: res.data.total
        }
      })
    },
    onMediaItemClick (item) {
      let isChose = false
      for (let i = 0; i < this.choseMedia.length && !isChose; i++) {
        if (this.choseMedia[i].id === item.id) {
          isChose = true
          // 移除
          this.choseMedia.splice(i, 1)
        }
      }
      if (!isChose) {
        this.choseMedia.push(item)
      }
    },
    onMediaItemDblclick (item) {
      this.insertHTML(item)
      this.mediaModalVisible = false
    },
    insertChoseMediaToHTML () {
      if (!this.choseMedia.length) {
        this.$message.warn('请至少选择一条数据')
      }
      this.choseMedia.map(item => {
        this.insertHTML(item)
      })
      this.mediaModalVisible = false
    },
    getMediaItemClass (item) {
      const classes = ['media-item', `media-item-${item.type}`]
      let isChose = false
      for (let i = 0; i < this.choseMedia.length && !isChose; i++) {
        if (this.choseMedia[i].id === item.id) {
          isChose = true
        }
      }
      if (isChose) {
        classes.push('media-item-active')
      }
      return classes
    }
  },
  beforeDestroy () {
    // 调用销毁 API 对当前编辑器实例进行销毁
    this.editor.destroy()
    this.editor = null
  }
}
</script>

<style lang="less">
@import "Input";
</style>
